package com.cimr.comm.controller.sso;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.cimr.comm.Constants;
import com.cimr.comm.aop.FullPage;
import com.cimr.comm.exception.SsoException;
import com.cimr.comm.po.SsoUserRel;
import com.cimr.comm.po.User;
import com.cimr.comm.service.SsoService;
import com.cimr.comm.service.UserService;
import com.cimr.comm.token.UserToken;
import com.cimr.comm.util.ConfUtil;
import com.cimr.comm.util.ShiroUtil;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.util.SavedRequest;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

/**
 * Created by liqi on 2018/5/21.
 * liqiwork@qq.com
 */
@Controller
@RequestMapping("/sso")
public class SsoLoginController {
    private final static Log log = LogFactory.get();

    @FullPage(menu = "sso_login")
    @RequestMapping({"login","nav/login"})
    public ModelAndView login(@RequestParam(required = true) String code,
                              ModelMap data, HttpServletRequest request, HttpServletResponse response) throws IOException, SsoException {

        HashMap<String, Object> paramMap = new HashMap<>();
        String authorization = "Basic " + Base64.encode(ConfUtil.getConf("sso.app.clientId")+":"+ConfUtil.getConf("sso.app.clientSecret"));
        paramMap.put("Authorization", authorization);
        paramMap.put("grant_type", "authorization_code");
        paramMap.put("code", code);
        paramMap.put("redirect_uri", ConfUtil.getConf("sso.app.loginUrl"));
        paramMap.put("scope", "all");
        paramMap.put("client_id", ConfUtil.getConf("sso.app.clientId"));
        paramMap.put("client_secret", ConfUtil.getConf("sso.app.clientSecret"));
        log.info("sso.tokenUrl.paramMap=="+paramMap.toString());

        // sso地址
        log.info("sso.tokenUrl=="+ConfUtil.getConf("sso.tokenUrl"));
        String result = HttpUtil.post(ConfUtil.getConf("sso.tokenUrl"), paramMap);
        log.info("sso.tokenUrl.result=="+result);
        if (result!=null && result.indexOf("access_token")>=0) {
            JSONObject jsonObject = JSONUtil.parseObj(result);
            String token = jsonObject.get("access_token").toString();
            // sso地址
            log.info("sso.meUrl=="+ConfUtil.getConf("sso.meUrl"));
            String result2 = HttpRequest.post(ConfUtil.getConf("sso.meUrl"))
                    .header("Authorization", "bearer "+token)
                    .execute().body();
            log.info("sso.meUrl.result=="+result2);

            JSONObject result2Json = JSONUtil.parseObj(result2);
            String userName = (String)result2Json.get("userName");
            if (userName!=null && !Objects.equals("",userName)) {
                List<SsoUserRel> rels = ssoService.getRelListBySsoUser(userName);
                if (rels.size()>0) {
                    SsoUserRel ssoUserRel = rels.get(0);
                    String appUser = ssoUserRel.getAppUser();
                    User user = userService.getByUsername(appUser);
                    UserToken userToken = new UserToken(user.getUsername(), user.getPswd());
                    // 登录应用系统
                    Subject subject = ShiroUtil.getSubject();
                    subject.login(userToken);SavedRequest savedRequest = WebUtils.getSavedRequest(request);
                    String url = "";
                    if (savedRequest==null || savedRequest.getRequestUrl()==null || savedRequest.getRequestUrl().equalsIgnoreCase(Constants.LOGIN_AJAX_URL)) {
                        url =  ConfUtil.getConf("main.indexPage");
                    } else {
                        // 跳转到登录前的页面
                        String contextPath = request.getContextPath();
                        url = StrUtil.removePrefix(savedRequest.getRequestUrl(), contextPath);
                    }

                    String contextPath = request.getServletContext().getContextPath();
                    url = contextPath + url;
                    response.sendRedirect(url);
                }
            }
        } else if (result!=null && result.indexOf("error")>=0) {
            JSONObject jsonObject = JSONUtil.parseObj(result);
            String msg = jsonObject.get("error_description").toString();
            throw new SsoException(msg);
        }

        return new ModelAndView("comm/sso/userNotExist");
    }

    @Autowired
    private SsoService ssoService;
    @Autowired
    private UserService userService;
}
